package cn.huangsm.advance.thread;

import java.util.concurrent.*;

/**
 * 异步化，优化请求响应时间
 *
 * @author huang
 * @PACKAGE_NAME cn.huangsm.advance.thread
 * @PROJECT_NAME advance-code
 * @date 2019/1/10
 */
public class AsyncPayMentService {
    /**
     * 设置核心池大小
     */

    int corePoolSize = 5;

    /**
     * 设置线程池缓存队列的排队策略为FIFO，并且指定缓存队列大小为5
     */
    BlockingQueue<PayMentRequest> workQueue = new LinkedBlockingQueue<>(5);


    /**
     * 创建一个核心线程数为1的线程池，销毁后会执行新的线程
     */
    //ExecutorService single = Executors.newSingleThreadExecutor();
    /**
     * 创建ScheduledThreadPoolExecutor线程池对象，并初始化该对象的各种参数
     */
    ThreadPoolExecutor single = new ScheduledThreadPoolExecutor(corePoolSize);

    /**
     * 可见化参数
     */
    private static volatile boolean flag = true;

    /**
     * 代码快调用初始化方法
     * 可以在启动的时候去初始化,通过@PostConstruct
     */ {
        init();
    }

    /**
     * 初始化将队列中的请求信息取出，然后调用doPay()方法
     */
    public void init() {
            single.execute(() -> {
                try {
                    PayMentRequest req = workQueue.take();
                    doPay(req);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
    }

    /**
     * 提交支付
     *
     * @param request
     * @return
     * @throws InterruptedException
     */
    public String submitPay(PayMentRequest request) throws InterruptedException {
        System.out.println("开始校验支付请求参数");
        Thread.sleep(2000);
        //异步执行
        //将请求添加到队列中
        workQueue.add(request);
        return "支付处理中";
    }

    /**
     * 调用第三方支付通道（使用阻塞队列方式优化）
     *
     * @param request
     * @return
     * @throws InterruptedException
     */
    private String doPay(PayMentRequest request) throws InterruptedException {
        System.out.println("开始处理支付请求:" + request);
        Thread.sleep(3000);
        return "success";
    }

    public static void main(String[] args) throws InterruptedException {
        Long start = System.currentTimeMillis();
        AsyncPayMentService asyncPayMentService = new AsyncPayMentService();
        PayMentRequest payMentRequest = new PayMentRequest();
        payMentRequest.setPayMethod(1);
        payMentRequest.setTotalFee(100);
        payMentRequest.setReturnUrl("http://www.huangsm.com/pay");
        asyncPayMentService.submitPay(payMentRequest);
        long end = System.currentTimeMillis();
        System.out.println("处理时间:" + (end - start));
    }
}
